package uscdb.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.log4j.Logger;

public class ZipUtil {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(ZipUtil.class);

	/**
	 * 功能：根据File对象压缩文件
	 * 
	 * @param zipOutFile
	 *            The file will be generated
	 * @param zipInputFile
	 *            To compress the file or folder
	 * @throws IOException
	 */
	public static boolean zipCompressing(File zipOutFile, File zipInputFile) {
		boolean flag = true;
		try {
			ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipOutFile));
			BufferedOutputStream bos = new BufferedOutputStream(zos);
			flag = zipCompressingStream(zos, zipInputFile, zipOutFile.getAbsolutePath(), bos);
			bos.close();
			zos.close();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return flag;
	}

	/**
	 * 功能：根据路径名压缩zip文件
	 * 
	 * @param zipFileName
	 *            The name of the zip file will be generated
	 * @param zipInputFile
	 *            To compress the file or folder
	 * @throws IOException
	 */
	public static boolean zipCompressing(String zipFileName, String zipInputFile) {
		return zipCompressing(new File(zipFileName), new File(zipInputFile));
	}

	/**
	 * 
	 * @param out
	 *            The implementation of file compression flow
	 * @param f
	 *            To compress the file or folder
	 * @param base
	 *            Root node of the compressed file
	 * @param bos
	 *            The compression stream buffer
	 * @throws IOException
	 */
	public static boolean zipCompressingStream(ZipOutputStream out, File f, String base, BufferedOutputStream bos)
			throws IOException {
		boolean flag = true;
		if (f.isDirectory()) {
			File[] f1 = f.listFiles();
			if (f1.length == 0) {
				out.putNextEntry(new ZipEntry(base + "/"));
			} else {
				for (int i = 0; i < f1.length; i++) {
					File file = f1[i];
					flag = flag && zipCompressingStream(out, file, file.getName(), bos);
				}
			}

		} else {
			out.putNextEntry(new ZipEntry(base));
			FileInputStream in = new FileInputStream(f);
			BufferedInputStream bis = new BufferedInputStream(in);
			int b;

			while ((b = bis.read()) != -1) {
				bos.write(b);
			}
			bos.flush();
			bis.close();
			in.close();
			flag = true;
		}
		return flag;
	}

	/**
	 * 功能：解压zip文件
	 * 
	 * @param zipFile
	 *            To unzip the files
	 * @param outputPath
	 *            Extract the location
	 */
	public static void zipDecompressing(File zipFile, String outputPath) {

		try {
			ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
			BufferedInputStream bis = new BufferedInputStream(zis);

			File fOut = null;
			ZipEntry entry = null;
			while ((entry = zis.getNextEntry()) != null && !entry.isDirectory()) {

				fOut = new File(outputPath, entry.getName());

				if (!fOut.exists()) {
					(new File(fOut.getParent())).mkdirs();
				}

				FileOutputStream fos = new FileOutputStream(fOut);

				BufferedOutputStream bos = new BufferedOutputStream(fos);
				int b;
				while ((b = bis.read()) != -1) {
					bos.write(b);
				}
				bos.close();
				fos.close();
			}
			bis.close();
			zis.close();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}

	}
}
